Реализация метода Dispose
https://learn.microsoft.com/ru-ru/dotnet/standard/garbage-collection/implementing-dispose


Отчистка неуправляемых и управляемых ресурсовclass BaseClassWithFinalizer : IDisposable
{
   // To detect redundant calls
   private bool _disposedValue;

    ~BaseClassWithFinalizer() => Dispose(false);

   // Public implementation of Dispose pattern callable by consumers.
   public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

   // Protected implementation of Dispose pattern.
   protected virtual void Dispose(bool disposing)
    {
       if (!_disposedValue)
        {
           if (disposing)
            {
               // TODO: dispose managed state (managed objects)
           }

           // TODO: free unmanaged resources (unmanaged objects) and override finalizer
           // TODO: set large fields to null
           _disposedValue = true;
        }
    }
}
Отчистка управляемых ресурсов
(Соответственно не использует финализацию).
public sealed class Foo : IDisposable
{
   private readonly IDisposable _disposable1;
   private readonly IDisposable _disposable2;

   public Foo()
    {
        _disposable1 = new Bar();
        _disposable2 = new Bar();
    }

   public void Dispose()
   {
     _disposable1.Dispose();
     _disposable2.Dispose();
   }
}
Наследование. Отчистка неуправляемых и управляемых ресурсов.class DerivedClassWithFinalizer : BaseClassWithFinalizer
{
   // To detect redundant calls
   private bool _disposedValue;

    ~DerivedClassWithFinalizer() => this.Dispose(false);

   // Protected implementation of Dispose pattern.
   protected override void Dispose(bool disposing)
    {
       if (!_disposedValue)
        {
           if (disposing)
            {
               // TODO: dispose managed state (managed objects).
           }

           // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
           // TODO: set large fields to null.
           _disposedValue = true;
        }

       // Call the base class implementation.
       base.Dispose(disposing);
    }
}
Пример использование механизма отчистки для воскрешения (resurrection) объекта.

Можно доработать для использования Dispose (не подавляется финализация, не выполняется повторная регистрация).
Если объект внутри себя использует другие финализируемые объекты, то внутри блока финализатора их состояние может быть недетерминировано (скорее всего их придется пересоздавать).
class A {
 private IObjectPool _pool = ...;

  ~A() {
   //will not die. keep a reference in resurectedA.
   _pool.ReturnToPool(this);
    GC.ReRegisterForFinalize(this);
  }
}
Dispose struct и упаковка (boxing)
Теги: